#include <AfxWin.h>
#include <node_api.h>
#include <assert.h>
#include <stdio.h>

/** 发送数据 */
void SendData(napi_env env, char* data, size_t len)
{
    napi_value nglobal, nsenddata;
    napi_status status = napi_get_global(env, &nglobal);
    if (status != napi_ok)
    {
        napi_throw_type_error(env, nullptr, "not find global");
        return;
    } 

    status = napi_get_named_property(env, nglobal, "senddata", &nsenddata);
    if (status != napi_ok)
    {
        napi_throw_type_error(env, nullptr, "not find senddata");
        return;
    }

    napi_value arg;
    char* sbuf;
    
    status = napi_create_buffer(env, len, (void**)&sbuf, &arg);
    if (status != napi_ok)
    {
        napi_throw_type_error(env, nullptr, "can not create buffer");
        return;
    } 
    memcpy(sbuf, data, len);
    napi_value* argv = &arg;

    napi_value return_val;
    status = napi_call_function(env, nglobal, nsenddata, 1, argv, &return_val);
    if (status != napi_ok)
    {
        napi_throw_type_error(env, nullptr, "call function error");
        return;
    } 
}

/** 接收到参数 */
napi_value RecvData(napi_env env, napi_callback_info info)
{
    napi_status status;
    size_t argc = 2;
    napi_value args[2];
    status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    assert(status == napi_ok);

    if (argc < 2)
    {
        napi_throw_type_error(env, nullptr, "Wrong number of arguments");
        return nullptr;
    }

    napi_valuetype vt0;
    status = napi_typeof(env, args[0], &vt0);
    assert(status == napi_ok);

    if (vt0 != napi_number)
    {
        napi_throw_type_error(env, nullptr, "Wrong arguments");
        return nullptr;
    }

    int tbid;
    char* data;
    size_t len;
    napi_get_value_int32(env, args[0], &tbid);
    napi_get_buffer_info(env, args[1], (void**)&data, &len);

    char str[64];
    sprintf(str, "%d %d %I64d %02x%02x%02x%02x", (tbid&0xFFFF0000)>>16, tbid&0xFFFF, len, data[0], data[1], data[2], data[3]);
    napi_value ret;
    napi_create_string_utf8(env, str, NAPI_AUTO_LENGTH, &ret);

    for(int i=0;i<len;i++){
        data[i]++;
    }
    SendData(env, data, len);

    return ret;
}

#define DECLARE_NAPI_METHOD(name, func)         \
    {                                           \
        name, 0, func, 0, 0, 0, napi_default, 0 \
    }

napi_value Init(napi_env env, napi_value exports)
{
    napi_status status;
    napi_property_descriptor desc = DECLARE_NAPI_METHOD("RecvData", RecvData);
    status = napi_define_properties(env, exports, 1, &desc);
    assert(status == napi_ok);
    return exports;
}

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)